home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / reve / procs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  14.8 KB  |  538 lines

  1. /*LINTLIBRARY*/
  2.  
  3. /*  @(#)procs.c 1.25 91/11/13
  4.  *
  5.  *  Procedures associated with the reve game panel items.
  6.  *
  7.  *  Copyright (C) 1990, 1991 - Rich Burridge & Yves Gallot.
  8.  *  All rights reserved.
  9.  *
  10.  *  Permission is granted to copy this source, for redistribution
  11.  *  in source form only, provided the news headers in "substantially
  12.  *  unaltered format" are retained, the introductory messages are not
  13.  *  removed, and no monies are exchanged.
  14.  *
  15.  *  Permission is also granted to copy this source, without the
  16.  *  news headers, for the purposes of making an executable copy by
  17.  *  means of compilation, provided that such copy will not be used
  18.  *  for the purposes of competition in any othello tournaments, without
  19.  *  prior permission from the authors.
  20.  *
  21.  *  No responsibility is taken for any errors on inaccuracies inherent
  22.  *  either to the comments or the code of this program, but if reported
  23.  *  (see README file), then an attempt will be made to fix them.
  24.  */
  25.  
  26. #include "color.h"
  27. #include "reve.h"
  28. #include "extern.h"
  29.  
  30.  
  31. void
  32. display_help()
  33. {
  34.   char str[4] ;
  35.   int val ;
  36.  
  37.   val = items[itemno].value ;
  38.   if (direction == INCREMENT && help_offsets[++val] != -1)
  39.     items[itemno].value++ ;
  40.   else if (direction == DECREMENT && help_offsets[--val] != -1)
  41.     items[itemno].value-- ;
  42.   else return ;
  43.   SPRINTF(str, "%d", items[itemno].value) ;
  44.   set_cycle(W_HELP, HELP_PAGE, str) ;
  45.   paint_help_text() ;
  46. }
  47.  
  48.  
  49. void
  50. do_edit()
  51. {
  52.   message(PANEL_MES, "Not currently implemented.") ;
  53. }
  54.  
  55.  
  56. void
  57. do_help()
  58. {
  59.   help_showing = !help_showing ;
  60.   set_frame(W_HELP, help_showing) ;
  61. }
  62.  
  63.  
  64. void
  65. do_stop()
  66. {
  67.   message(PANEL_MES, "Not currently implemented.") ;
  68. }
  69.  
  70.  
  71. void
  72. do_props()
  73. {
  74.   props_showing = !props_showing ;
  75.   set_frame(W_PROPS, props_showing) ;
  76. }
  77.  
  78.  
  79. void
  80. do_selection(state)
  81. int state ;
  82. {
  83.   int cx, cy ;
  84.  
  85.   cx = (piece_x + pieceXrad - bborder) / cell_width ;
  86.   cy = (piece_y + pieceYrad - bborder) / cell_height ;
  87.  
  88.   set_cursor(CANVASCUR) ;
  89.   if (state == LEFT_DOWN)
  90.     {
  91.       draw_outline(cy * BOARD_SIZE + cx, IS_ON) ;
  92.       if (ANIMATION) draw_piece(next_player, piece_x, piece_y, RINV) ;
  93.       cmode = (enum cantype) ((int) cmode - 1) ;
  94.     }
  95.   else
  96.     {
  97.       if (ANIMATION) draw_piece(next_player, piece_x, piece_y, RINV) ;
  98.       draw_outline(last_outline, IS_OFF) ;
  99.       move = cy * BOARD_SIZE + cx ;
  100.       update_clock(next_player, TRUE) ;
  101.       make_move() ;
  102.     }
  103. }
  104.  
  105.  
  106. void
  107. do_suggest(player, move, note, state)
  108. int player, move, note ;
  109. enum bltype state ;
  110. {
  111.   int count ;
  112.  
  113.   set_cursor(CANVASCUR) ;
  114.  
  115.   if (move == -1) return ;
  116.   if (best_cmove != -1 && DO_BESTMOVE)
  117.     {
  118.       draw_square(best_cmove, IS_OFF, 2) ;
  119.       if (DO_NUMBER) show_number(best_cmove, cmove_depth, IS_OFF) ;
  120.     }
  121.  
  122.   draw_symbol(S_SUGGEST, move, state) ;
  123.   if (show_moves && state == IS_OFF) draw_symbol(S_MOVE, move, IS_ON) ;
  124.   if (show_moves || state == IS_ON)
  125.     {
  126.       count = legal(move, player, &board) ;
  127.       show_number(move, count, IS_ON) ;
  128.     }
  129.   if (SHOW_NOTES && state == IS_ON) set_eval(player, move, note) ;
  130. }
  131.  
  132.  
  133. void
  134. init_help_file(helpfile)     /* Load reve help page offsets. */
  135. char *helpfile ;
  136. {
  137.   char buf[MAXLINE] ;
  138.   int i, page ;
  139.   long offset ;
  140.  
  141.   for (i = 0; i < MAXPAGES; i++) help_offsets[i] = -1 ;
  142.   if ((hfp = find_file(helpfile)) == NULL)
  143.     {
  144.       FPRINTF(stderr, "Cannot open online help file\n") ;
  145.       return ;
  146.     }
  147.   page = 1 ;
  148.   for (;;)
  149.     {
  150.       offset = ftell(hfp) ;
  151.       if (fgets(buf, MAXLINE, hfp) == NULL) return ;
  152.       if (EQUAL(buf, "REVE(6)")) help_offsets[page++] = offset ;
  153.     }
  154. }
  155.  
  156.  
  157. void
  158. make_move()
  159. {
  160.   if (legal(move, next_player, &board) == 0)
  161.     {
  162.       invalid = TRUE ;
  163.       message(PANEL_MES, "Invalid move") ;
  164.       cmode = (enum cantype) ((int) cmode - 1) ;
  165.       if (SHOW_LEGAL) show_all(IS_ON) ;
  166.       return ;
  167.     }
  168.   do_move(next_player) ;
  169.   invalid = FALSE ;
  170.  
  171.   switch (dtype)
  172.     {
  173.       case XBLACK :
  174.       case XWHITE : opponent_move(OPPONENT(next_player)) ;
  175.                     break ;
  176.       case XBOTH  : if (check(OPPONENT(next_player)) == TRUE) break ;
  177.                     (void) check(next_player) ;
  178.                     return ;
  179.     }
  180.   cmode       = (enum cantype) (OPPONENT(next_player) + 1) ;
  181.   next_player = OPPONENT(next_player) ;
  182. }
  183.  
  184.  
  185. void
  186. new_game()
  187. {
  188.   initboard() ;
  189.   cmode = BLACK_START ;
  190.   last_move = -1 ;
  191.   if (items[(int) BLACK_PLAYS].value == COMPUTER) first_move = 1 ;
  192.   init_clocks() ;
  193.   paint_all() ;
  194.   message(EVAL_MES, "") ;
  195.   message(PANEL_MES, "Use left mouse button to move") ;
  196.   draw_button(W_PANEL, NEW_GAME_BUT, C_ITEMS, BUT_NORMAL) ;
  197. }
  198.  
  199.  
  200. void
  201. opt_toggle(val)
  202. int *val ;
  203. {
  204.   if (*val) *val = FALSE ;
  205.   else      *val = TRUE ;
  206. }
  207.  
  208.  
  209. void
  210. redo()
  211. {
  212.   enum panel_type p ;
  213.  
  214.  /*  The amount we redo is dependant upon two things:
  215.   *
  216.   *  1/ Whether the opponent is the computer, in which case we redo
  217.   *     two "moves". Otherwise we just redo one "move".
  218.   *
  219.   *  2/ A "move" is considered to be all consecutive moves by the opponent.
  220.   */
  221.  
  222.   redo_move(next_player) ;
  223.   p = (next_player == BLACK) ? BLACK_PLAYS : WHITE_PLAYS ;
  224.   if (items[(int) p].value == COMPUTER) redo_move(next_player) ;
  225.  
  226.   set_score() ;
  227.   set_turn(next_player) ;
  228. }
  229.  
  230.  
  231. void
  232. redo_move(player)
  233. int player ;
  234. {
  235.   int i, m, n, x, y ;
  236.  
  237.   m = n = 64 - board.moves_left ;
  238.   while (moves[n].move != -1 && moves[n].player == player) n++ ;
  239.   n-- ;
  240.  
  241.   if (n < m || n > 63) message(PANEL_MES, "No moves to redo.") ;
  242.   else
  243.     {
  244.       if (DO_LAST)    show_last(last_move, IS_OFF) ;
  245.       if (DO_NUMBER)  show_number(last_move, 60 - board.moves_left, IS_OFF) ;
  246.       if (show_moves) show_all(IS_OFF) ;
  247.       do_suggest(player, suggestion, note, IS_OFF) ;
  248.       FOR_BOARD(i)
  249.         {
  250.           if (moves[n].square[i] != board.square[i])
  251.             {
  252.               get_xy(i, &x, &y) ;
  253.               if (moves[n].square[i] == FREE)
  254.                 color_area(W_BOARD, x, y,
  255.                            2 * pieceXrad, 2 * pieceYrad, W_COLOR(C_SQUARE)) ;
  256.               else draw_piece(moves[n].square[i], x, y, RSRC) ;
  257.             }
  258.           board.square[i] = moves[n].square[i] ;
  259.         }
  260.       board.moves_left = moves[n].moves_left ;
  261.       board.player     = moves[n].player ;
  262.       board.move       = moves[n].move ;
  263.       board.note       = moves[n].note ;
  264.       board.timeleft   = moves[n].timeleft ;
  265.       last_move        = board.move ;
  266.  
  267.       FOR_BOARD(i) old_board.square[i] = moves[n-1].square[i] ;
  268.       old_board.moves_left = moves[n-1].moves_left ;
  269.       old_board.player     = moves[n-1].player ;
  270.       old_board.move       = moves[n-1].move ;
  271.       old_board.note       = moves[n-1].note ;
  272.       old_board.timeleft   = moves[n-1].timeleft ;
  273.  
  274.       timeleft = board.timeleft ;
  275.       reset_time(timeleft) ;
  276.  
  277.       if (OPPONENT(player) == BLACK) cmode = BLACK_START ;
  278.       else                           cmode = WHITE_START ;
  279.       message(PANEL_MES, "") ;
  280.  
  281.       if (DO_LAST)    show_last(last_move, IS_ON) ;
  282.       if (DO_NUMBER)  show_number(last_move, 60 - board.moves_left, IS_ON) ;
  283.       if (SHOW_NOTES) set_eval(board.player, board.move, board.note) ;
  284.       else message(EVAL_MES, "") ;
  285.       next_player = OPPONENT(board.player) ;
  286.     }
  287. }
  288.  
  289.  
  290. void
  291. set_computer(val)
  292. int val ;
  293. {
  294.   int curi ;
  295.  
  296.   if (val == CP_WHITE)
  297.     {
  298.       dtype = XBLACK ;
  299.       play_computer = TRUE ;
  300.       items[(int) BLACK_PLAYS].value = HUMAN ;
  301.       STRCPY(items[(int) BLACK_PLAYS].text, player_values[HUMAN]) ;
  302.       items[(int) WHITE_PLAYS].value = COMPUTER ;
  303.       STRCPY(items[(int) WHITE_PLAYS].text, player_values[COMPUTER]) ;
  304.     }
  305.   else if (val == CP_BLACK)
  306.     {
  307.       dtype = XWHITE ;
  308.       play_computer = TRUE ;
  309.       items[(int) BLACK_PLAYS].value = COMPUTER ;
  310.       STRCPY(items[(int) BLACK_PLAYS].text, player_values[COMPUTER]) ;
  311.       items[(int) WHITE_PLAYS].value = HUMAN ;
  312.       STRCPY(items[(int) WHITE_PLAYS].text, player_values[HUMAN]) ;
  313.     }
  314.   else if (val == CP_NEITHER)
  315.     {
  316.       dtype = XBOTH ;
  317.       play_computer = FALSE ;
  318.       items[(int) BLACK_PLAYS].value = HUMAN ;
  319.       STRCPY(items[(int) BLACK_PLAYS].text, player_values[HUMAN]) ;
  320.       items[(int) WHITE_PLAYS].value = HUMAN ;
  321.       STRCPY(items[(int) WHITE_PLAYS].text, player_values[HUMAN]) ; 
  322.     }
  323.  
  324.   draw_choice(W_PROPS, COMP_CHOICE, W_COLOR(C_PANEL)) ;
  325.   make_message(W_PANEL, BLACK_PLAYS) ;
  326.   make_message(W_PANEL, WHITE_PLAYS) ;
  327.  
  328.   if (next_player == BLACK) curi = items[(int) BLACK_PLAYS].value ;
  329.   else                      curi = items[(int) WHITE_PLAYS].value ;
  330.   if (curi == COMPUTER)
  331.     if ((next_player == BLACK && cmode == BLACK_START) ||
  332.         (next_player == WHITE && cmode == WHITE_START))
  333.       opponent_move(next_player) ;
  334. }
  335.  
  336.  
  337. void
  338. set_option()
  339. {
  340.   char str[4] ;
  341.   int maxw, n, val ;
  342.  
  343.   switch (itemno)
  344.     {
  345.       case COMP_CHOICE : maxw = items[itemno].width / items[itemno].nopts ;
  346.                          val = (curx - items[itemno].x) / maxw ;
  347.                          if (val != CP_BOTH)
  348.                            {
  349.                              items[itemno].value = val ;
  350.                              set_computer(val) ;
  351.                            }
  352.                          else message(PANEL_MES,
  353.                                "Computer plays both is not implemented yet.") ;
  354.                          break ;
  355.  
  356.       case DIFF_CHOICE : maxw = items[itemno].width / items[itemno].nopts ;
  357.                          val = (curx - items[itemno].x) / maxw ;
  358.                          level = val + 1 ;
  359.                          items[itemno].value = val ;
  360.                          draw_choice(W_PROPS, DIFF_CHOICE, W_COLOR(C_PANEL)) ;
  361.  
  362.                          items[(int) MAX_DEPTH].value = 0 ;
  363.                          set_cycle(W_PROPS, MAX_DEPTH, "off") ;
  364.                          break ;
  365.  
  366.       case MAX_DEPTH   : val = items[itemno].value ;
  367.                          if (direction == INCREMENT && val < MAX_PROFMAX)
  368.                            items[itemno].value++ ;
  369.                          else if (direction == DECREMENT && val > 0)
  370.                            items[itemno].value-- ;
  371.                          if (!items[(int) itemno].value) STRCPY(str, "off") ;
  372.                          else SPRINTF(str, "%d", items[itemno].value) ;
  373.                          set_cycle(W_PROPS, MAX_DEPTH, str) ;
  374.  
  375.                          if (items[itemno].value)
  376.                            {
  377.                              items[(int) DIFF_CHOICE].value = -1 ;
  378.                              level = 1 ;
  379.                              max_depth = items[itemno].value ;
  380.                            }
  381.                          else
  382.                            {
  383.                              items[(int) DIFF_CHOICE].value = old_diffval ;
  384.                              level = old_diffval + 1 ;
  385.                              max_depth = 2 ;
  386.                            }
  387.                          draw_choice(W_PROPS, DIFF_CHOICE, W_COLOR(C_PANEL)) ;
  388.                          break ;
  389.  
  390.       case OPT_ANIM    : opt_toggle(&ANIMATION) ;
  391.                          break ;
  392.  
  393.       case OPT_BEST    : opt_toggle(&DO_BESTMOVE) ;
  394.                          break ;
  395.  
  396.       case OPT_LAST    : opt_toggle(&DO_LAST) ;
  397.                          n = 63 - board.moves_left ;
  398.                          show_last(moves[n].move, DO_LAST) ;
  399.                          break ;
  400.  
  401.       case OPT_EVAL    : opt_toggle(&SHOW_NOTES) ;
  402.                          if (SHOW_NOTES == FALSE) message(EVAL_MES, "") ;
  403.                          break ;
  404.  
  405.       case OPT_NUM     : opt_toggle(&DO_NUMBER) ;
  406.                          n = 63 - board.moves_left ;
  407.                          if (board.moves_left < 60)
  408.                            show_number(moves[n].move, 60 - board.moves_left,
  409.                                        DO_NUMBER) ;
  410.                          break ;
  411.  
  412.       case OPT_FLIP    : opt_toggle(&QUICKGAME) ;
  413.                          break ;
  414.  
  415.       case OPT_MOVE    : opt_toggle(&SHOW_LEGAL) ;
  416.                          break ;
  417.  
  418.       case OPT_CLK     : opt_toggle(&DO_CLOCK) ;
  419.                          draw_clock(W_PANEL, BLACK_CLOCK, DO_CLOCK) ;
  420.                          draw_clock(W_PANEL, WHITE_CLOCK, DO_CLOCK) ;
  421.     }
  422. }
  423.  
  424.  
  425. void
  426. show_all_moves()
  427. {
  428.   if (show_moves) show_all(IS_OFF) ;
  429.   else            show_all(IS_ON) ;
  430. }
  431.  
  432.  
  433. void
  434. suggest()
  435. {
  436.   int player ;
  437.  
  438.   if (cmode == GAME_OVER) return ;
  439.   if (cmode == WHITE_START) player = WHITE ;
  440.   else                      player = BLACK ;
  441.   if (suggestion != -1)
  442.     {
  443.       sstate = (enum bltype) !((int) sstate) ;
  444.       do_suggest(player, suggestion, snote, sstate) ;
  445.     }
  446.   else
  447.     {
  448.       set_cursor(HOURGLASS) ;
  449.       restore_moves = show_moves ;
  450.       if (show_moves) show_all(IS_OFF) ;
  451.       write_to_reve(M_SUGGESTION, board.square, player, level) ;
  452.     }
  453. }
  454.  
  455.  
  456. void
  457. undo()
  458. {
  459.   enum panel_type p ;
  460.  
  461.  /*  The amount we undo is dependant upon two things:
  462.   *
  463.   *  1/ Whether the opponent is the computer, in which case we undo
  464.   *     two "moves". Otherwise we just undo one "move".
  465.   *
  466.   *  2/ A "move" is considered to be all consecutive moves by the opponent.
  467.   */
  468.  
  469.   undo_move(next_player) ;
  470.   p = (next_player == BLACK) ? BLACK_PLAYS : WHITE_PLAYS ;
  471.   if (items[(int) p].value == COMPUTER) undo_move(next_player) ;
  472.  
  473.   set_score() ;
  474.   set_turn(next_player) ;
  475. }
  476.  
  477.  
  478. void
  479. undo_move(player)
  480. int player ;
  481. {
  482.   int i, limit, n, x, y ;
  483.  
  484.   n = 63 - board.moves_left ;
  485.   while (moves[n].player != player) n-- ;
  486.  
  487.   limit = (items[(int) BLACK_PLAYS].value == COMPUTER) ? 4 : 3 ;
  488.   if (n >= limit)
  489.     {
  490.       if (DO_LAST)    show_last(last_move, IS_OFF) ;
  491.       if (DO_NUMBER)  show_number(last_move, 60 - board.moves_left, IS_OFF) ;
  492.       if (show_moves) show_all(IS_OFF) ;
  493.       do_suggest(player, suggestion, note, IS_OFF) ;
  494.       FOR_BOARD(i)
  495.         {
  496.           if (moves[n].square[i] != board.square[i])
  497.             {
  498.               get_xy(i, &x, &y) ;
  499.               if (moves[n].square[i] == FREE)
  500.                 color_area(W_BOARD, x, y,
  501.                            2 * pieceXrad, 2 * pieceYrad, W_COLOR(C_SQUARE)) ;
  502.               else draw_piece(moves[n].square[i], x, y, RSRC) ;
  503.             }
  504.           board.square[i] = moves[n].square[i] ;
  505.         }
  506.       board.moves_left = moves[n].moves_left ;
  507.       board.player     = moves[n].player ;
  508.       board.move       = moves[n].move ;
  509.       board.note       = moves[n].note ;
  510.       board.timeleft   = moves[n].timeleft ;
  511.       last_move        = board.move ;
  512.  
  513.       FOR_BOARD(i) old_board.square[i] = moves[n-1].square[i] ;
  514.       old_board.moves_left = moves[n-1].moves_left ;
  515.       old_board.player     = moves[n-1].player ;
  516.       old_board.move       = moves[n-1].move ;
  517.       old_board.note       = moves[n-1].note ;
  518.       old_board.timeleft   = moves[n-1].timeleft ;
  519.  
  520.       timeleft = board.timeleft ;
  521.       reset_time(timeleft) ;
  522.  
  523.       if (OPPONENT(player) == BLACK) cmode = BLACK_START ;
  524.       else                           cmode = WHITE_START ;
  525.       message(PANEL_MES, "") ;
  526.  
  527.       if (n > 3)
  528.         {
  529.           if (DO_LAST)   show_last(last_move, IS_ON) ;
  530.           if (DO_NUMBER) show_number(last_move, 60 - board.moves_left, IS_ON) ;
  531.           if (SHOW_NOTES) set_eval(board.player, board.move, board.note) ;
  532.         }
  533.       else message(EVAL_MES, "") ;
  534.       next_player = OPPONENT(board.player) ;
  535.     }
  536.   else message(PANEL_MES, "No moves to undo.") ;
  537. }
  538.